package com.zhoulz.homework.chaptor02.node;

import io.netty.bootstrap.Bootstrap;
import io.netty.channel.Channel;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioSocketChannel;

import java.net.ConnectException;

import org.apache.log4j.Logger;

/**
 * 客户端
 * @author zhoulz
 *
 */
public class Client {
	Logger log = Logger.getLogger(Client.class);
	
	private String name;// 客户端节点名
	private String toNodeName;// 对端节点名
	private String host;
	private int port;
	
	ChannelFuture cf;
	EventLoopGroup group = new NioEventLoopGroup();
	private PacketClientChannelInboundHandler packetInboundHandler;

	public Client(String name, String toNodeName, String host, int port){
		this.name = name;
		this.toNodeName = toNodeName;
		this.host = host;
		this.port = port;
	}
	
	public void start() throws Exception{
		
		try {
			Bootstrap bootstrap = new Bootstrap();
			bootstrap.group(group)
			.channel(NioSocketChannel.class)
			.remoteAddress(host, port)
			.handler(new ChannelInitializer<Channel>() {

				@Override
				protected void initChannel(Channel ch) throws Exception {
					packetInboundHandler = new PacketClientChannelInboundHandler(name, toNodeName);
					ch.pipeline().addLast(packetInboundHandler);
				}
				
			});
			cf = bootstrap.connect().sync();
			log.info(String.format("%s连接远程节点%s（%s:%s），准备发送文件！", name, toNodeName, host, port));
			// 添加到操作类，供command用
			CmdHelper.addClient(this);
			
			cf.channel().closeFuture().sync();
			log.info("文件发送完成，关闭连接："+toNodeName);
		}  catch (Exception e) {
			if(e instanceof ConnectException || e instanceof InterruptedException){
				log.info("关闭连接："+toNodeName);
			}else{
				log.error("启动TCP客户端失败！", e);
			}
		}finally{
			group.shutdownGracefully().sync();
		}
	}
	public void shutdown(){
		packetInboundHandler.setStop(true);
		try {
			cf.await();
		} catch (InterruptedException e) {
			log.error("shutdown失败", e);
		}
	}
	
	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public String getToNodeName() {
		return toNodeName;
	}

	public void setToNodeName(String toNodeName) {
		this.toNodeName = toNodeName;
	}

	public static void main(String[] args) throws Exception {
		//new Client("127.0.0.1", 8004).start("leader-3", "leader-4");
	}
}